home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
9-Digit Zip Code Directory
/
9-Digit Zip Code Directory (American Business Information) (ABIZIP-12).ISO
/
z4src.zip
/
BSSTR.C
< prev
next >
Wrap
C/C++ Source or Header
|
1995-06-08
|
20KB
|
667 lines
//----------------------------------------------------------------------------
// MODULE DESCRIPTION
//
// Module: bsstr.c
// Title: Base library
// Notice: John M. Weeder
// Copyright (c) 1993. All rights reserved.
// This module contains proprietary information and should be
// treated as confidential.
//
//----------------------------------------------------------------------------
// MAINTENANCE HISTORY
//
// $Workfile$
// $Revision$
// $Author$
// $Date$
// $Log$
//
//----------------------------------------------------------------------------
// MODULE NARRATIVE
//
//
// This module contains utility string functions.
//
// The code in this module should be written entirely in C.
// Do not use any C++ constructs.
//
// This module is portable to:
// DOS 3.X+
// MS Windows 3.X+
// OS/2 2.X+
// OS/2 2.0 PM
// SCO UNIX.
//
// The following compilers are supported:
// MSC 6.0A
// MSC/C++ 7.0
// Borland C++ 3.1 for DOS
// Borland C++ 1.0 for OS/2 2.X
// SCO UNIX cc
//
//----------------------------------------------------------------------------
#include <bs.h>
//----------------------------------------------------------------------------
// UNIX Portability.
// This is a hack but it kind of works...
//----------------------------------------------------------------------------
#if OS_UNIX
# define strtoul strtol
#endif
//----------------------------------------------------------------------------
// Description: Sort routine used by qsort to sort an array of pointers
// to strings.
// Parameters: see qsort()
// Returns: see qsort()
//----------------------------------------------------------------------------
static int __strsort__(const void *pv1, const void *pv2)
{
return strcmp(*((PPSZ)pv1), *((PPSZ)pv2));
}
//----------------------------------------------------------------------------
// Description: Convert a length of consectutive null terminated strings,
// ending with a double NULL into an array. An array of
// sufficient size will be allocated if needed. Array is
// NULL terminated.
// Parameters: psz Pointer to array of strings.
// ppsz Pointer to array of string pointers. If NULL, an
// array will be allocated.
// cArray Size of string pointer array.
// Returns: Pointer to array.
//----------------------------------------------------------------------------
PPSZ FN_E str2array(PSZ psz, PPSZ ppsz, SIZET cArray)
{
SIZET i, cCount;
Assert(psz);
cCount = strarraysize(psz);
if (!ppsz)
{
if ((ppsz = (PPSZ)MemAlloc((cCount + 1) * sizeof(PSZ))) == NULL)
return NULL;
}
if (!cArray)
cArray = cCount + 1;
for (i = 0; i < cArray - 1; ++i)
{
ppsz[i] = psz;
psz = strchr(psz, '\0') + 1;
}
ppsz[i] = NULL; // NULL terminate list
return ppsz;
}
//----------------------------------------------------------------------------
// Description: Convert an array of pointers to string to a single array
// of strings with a double NULL at the end.
// An array is allocated for the concatenated strings if
// needed.
// Parameters: ppsz Pointer to array of string pointers. The array
// must be null terminated.
// cCount Number of elements in array, 0 = search for null
// terminator.
// psz Buffer.
// If null, a buffer of the correct size is allocated.
// Returns: Pointer to array.
//----------------------------------------------------------------------------
PSZ FN_E strarray2str(PPSZ ppsz, SIZET cCount, PSZ pszBuf)
{
SIZET i, cSize, cLen;
PSZ psz;
Assert(ppsz);
if (!cCount)
cCount = strarraycnt(ppsz);
for (cSize = i = 0; i < cCount; ++i)
{
cLen = strlen(ppsz[i]);
if (MAX_SIZET - cSize - 1 < cLen)
return NULL; // Bigger than 64K
cSize += cLen + 1;
if (cSize == MAX_SIZET)
return NULL; // No room for double null
}
if (pszBuf == NULL)
if ((pszBuf = (PSZ)MemAlloc(cSize)) == NULL)
return NULL;
for (psz = pszBuf, i = 0; i < cCount; ++i)
{
strcpy(psz, ppsz[i]);
psz = strchr(psz, '\0') + 1;
}
psz[0] = '\0'; // Add second null
return pszBuf;
}
//----------------------------------------------------------------------------
// Description: Counts the number of string pointers in a NULL
// terminated array
// Parameters: ppszStr Pointer to an array of pointers.
// Returns: Number of strings found (Array is null terminated)
//----------------------------------------------------------------------------
SIZET FN_E strarraycnt(PPSZ ppsz)
{
SIZET i = 0;
Assert(ppsz);
for (i = 0; ppsz[i]; ++i)
;
return i;
}
//----------------------------------------------------------------------------
// Description: Sort an array of pointers to strings in ascending order.
// Parameters: psz String to match
// ppsz Pointer to array of string pointers. The array
// must be null terminated.
// cCount Number of elements in array, 0 = search for null
// terminator.
// Returns: Pointer to matched element or NULL
//----------------------------------------------------------------------------
PCSZ FN_E strarrayfind(PSZ psz, PPSZ ppsz, SIZET cCount)
{
Assert(psz && ppsz);
if (cCount == 0)
cCount = strarraycnt(ppsz);
if (cCount)
{
ppsz = (PPSZ)bsearch(&psz, ppsz, cCount, sizeof(PSZ), __strsort__);
psz = ppsz ? *ppsz: NULL;
}
else
psz = NULL;
return psz;
}
//----------------------------------------------------------------------------
// Description: Determine the number of strings in an array of ascii text
// terminated with a double null.
// Parameters: psz Pointer to array of strings.
// Returns: Number of null terminated strings in array.
//----------------------------------------------------------------------------
SIZET FN_E strarraysize(PCSZ pcsz)
{
SIZET i = 0;
Assert(pcsz);
for (;;)
{
pcsz = strchr(pcsz, '\0') + 1;
i++;
if (pcsz[0] == '\0')
break;
}
return i;
}
//----------------------------------------------------------------------------
// Description: Sort an array of pointers to strings in ascending order.
// Parameters: ppsz Pointer to array of string pointers. The array
// must be null terminated.
// cCount Number of elements in array, 0 = search for null
// terminator.
// Returns: TRUE if successful.
//----------------------------------------------------------------------------
BOOL FN_E strarraysort(PPSZ ppsz, SIZET cCount)
{
Assert(ppsz);
if (cCount == 0)
cCount = strarraycnt(ppsz);
if (cCount > 1)
qsort(ppsz, cCount, sizeof(PSZ), __strsort__);
return TRUE;
}
//----------------------------------------------------------------------------
// Description: Concatenate a string. Placing single space between the
// strings.
// Does not add a space if the destination is empty or already
// contains a space.
// Parameters: pszDst Pointer to destination string.
// pcszSrc Pointer to source string
// Returns: Pointer to destination
//----------------------------------------------------------------------------
PSZ FN_E strcats(PSZ pszDst, PCSZ pcszSrc)
{
PSZ psz;
Assert(pszDst && pcszSrc);
// Skip wshitespace in source
while (pcszSrc[0] && isascii(pcszSrc[0]) && isspace(pcszSrc[0]))
pcszSrc++;
if (!pcszSrc[0]) // String contained only whitespace
return pszDst;
psz = strchr(pszDst, '\0'); // Append space if needed
if (pszDst[0] && (!isascii(*(psz - 1)) || !isspace(*(psz - 1))))
*psz++ = ' ';
strcpy(psz, pcszSrc);
return (PSZ)pszDst;
}
//----------------------------------------------------------------------------
// Description: Count the number of characters 'c' in a string
// Parameters: psz String
// c Character to count
// Returns: Number of characters
//----------------------------------------------------------------------------
SIZET FN_E strcnt(PSZ psz, CHAR ch)
{
SIZET cCount = 0;
Assert(psz);
for (; psz[0]; ++psz) // Count characters
if (psz[0] == ch)
cCount++;
return cCount;
}
//----------------------------------------------------------------------------
// Description: Delete a sub-string from a string.
// Parameters: psz String
// cOffset Offset to delete at
// cCount Number of characters to delete
// Returns: Pointer to string.
//----------------------------------------------------------------------------
PSZ FN_E strdel(PSZ psz, SIZET cOffset, SIZET cCount)
{
Assert(psz);
memdel((PVOID)psz, strlen(psz) + 1, cOffset, cCount);
return psz;
}
//----------------------------------------------------------------------------
// Description: Extracts an element from a delimited list.
// Parameters: psz Buffer for results.
// pcszList List to search.
// cWhich Which component. 0..n-1
// pcszSep List of separators
// Returns: TRUE if successful and element
//----------------------------------------------------------------------------
BOOL FN_E strextract(PSZ psz, PCSZ pcszList, SIZET cWhich, PCSZ pcszSep)
{
Assert(psz && pcszList && pcszSep);
while (pcszList[0])
{
SIZET cb = strcspn(pcszList, pcszSep);
if (cWhich == 0)
{
memcpy(psz, pcszList, cb);
psz[cb] = '\0';
return TRUE;
}
cWhich--;
pcszList += cb;
if (pcszList[0])
pcszList++;
}
return FALSE;
}
//----------------------------------------------------------------------------
// Description: Create a hash value for a sting into a ULONG.
// Parameters: pszHash Name to create a hash value for.
// Returns: Hash value for name.
//----------------------------------------------------------------------------
ULONG FN_E strhash(PCSZ pszHash)
{
Assert(pszHash);
return (ULONG)CrcCalc((PBYTE)pszHash, strlen(pszHash));
}
//----------------------------------------------------------------------------
// Description: Insert a string into another string. Assumes there is
// sufficient space for the expanded buffer.
// Parameters: psz Destination string
// pszIns String to insert
// cOffset Offset to add add.
// Returns: Pointer to buffer.
//----------------------------------------------------------------------------
PSZ FN_E strins(PSZ psz, PSZ pszIns, SIZET cOffset)
{
SIZET cLen, cIns;
Assert(psz && pszIns);
cLen = strlen(psz) + 1;
cIns = strlen(pszIns);
memins(psz, cLen, pszIns, cIns, MIN(cOffset, cLen));
return psz;
}
//----------------------------------------------------------------------------
// Description: Insert a string into another string. Assumes there is
// sufficient space for the expanded buffer.
// Parameters: psz Destination string
// pszIns String to insert
// cOffset Offset to add add.
// Returns: Pointer to buffer.
//----------------------------------------------------------------------------
PSZ FN_E strinsc(PSZ psz, CHAR chIns, SIZET cOffset)
{
SIZET cLen;
Assert(psz);
cLen = strlen(psz) + 1;
memins(psz, cLen, &chIns, 1, MIN(cOffset, cLen));
return psz;
}
//----------------------------------------------------------------------------
// Description: Copy up to 'cch' chars from the source string to the destination
// string. This function always guarantees the destination string
// is NULL terminated.
// Parameters: pszDest Destination string
// pszSrc Source string.
// cch Size of destination buffer.
// Returns: Pointer to destination string.
//----------------------------------------------------------------------------
PSZ FN_E strnzcpy(PSZ pszDest, PCSZ pszSrc, SIZET cch)
{
Assert(pszDest && pszSrc);
if (cch == 1)
pszDest[0] = '\0'; // A trivial buffer size
else if (cch > 1)
{
SIZET cbLen = strlen(pszSrc); // Get length of source string
if (cbLen >= cch)
{
memcpy(pszDest, pszSrc, cch - 1);
pszDest[cch - 1] = '\0';
}
else
strcpy(pszDest, pszSrc); // String fits
}
return pszDest; // return destination
}
//----------------------------------------------------------------------------
// Description: Return the ordinal suffix for a number.
// Parameters: lVal Number
// Returns: Pointer to ordinal suffix (capitalized)
//----------------------------------------------------------------------------
PSZ FN_E strord(LONG lVal)
{
if ((lVal % 100) > 10 && (lVal %100) <14)
return "TH";
if ((lVal % 10) == 1)
return "ST";
if ((lVal % 10) == 2)
return "ND";
if ((lVal % 10) == 3)
return "RD";
return "TH";
}
//----------------------------------------------------------------------------
// Description: Skip to next whittespace character in string.
// Parameters: psz String
// Returns: Pointer to first non-whitespace character in string
// or NULL.
//----------------------------------------------------------------------------
PSZ FN_E strskip2ws(PSZ psz)
{
if (psz == NULL)
return NULL;
while (psz[0] != '\0' && isascii(psz[0]) && !isspace(psz[0]))
psz++;
return psz[0] ? psz: NULL;
}
//----------------------------------------------------------------------------
// Description: Skip over whitespace in a string
// Parameters: psz Pointer to string.
// Returns: TRUE if successful.
//----------------------------------------------------------------------------
PSZ FN_E strskipws(PCSZ psz)
{
if (psz == NULL)
return NULL;
while (psz[0] && isascii(psz[0]) && isspace(psz[0]))
psz++;
return (PSZ)psz;
}
//----------------------------------------------------------------------------
// Description: Skip over whitespace in a string
// Parameters: psz Pointer to string.
// Returns: TRUE if successful.
//----------------------------------------------------------------------------
PSZ FN_E strskipzero(PCSZ psz)
{
if (psz == NULL)
return NULL;
if (psz[0] == '0')
{
while (psz[0] == '0')
psz++;
if (!isascii(psz[0]) || !isdigit(psz[0]))
psz--;
}
return (PSZ)psz;
}
//----------------------------------------------------------------------------
// Description: Strip all control characters from a string
// Parameters: psz String.
// Returns: Pointer to string
//----------------------------------------------------------------------------
PSZ FN_E strstripcntrl(PSZ psz)
{
PSZ pszDst = psz;
Assert(psz);
do
{
if (!iscntrl(psz[0]))
*pszDst++ = *psz++;
else
psz++;
}
while (psz[0]);
pszDst[0] = '\0';
return psz;
}
//----------------------------------------------------------------------------
// Description: Trim space from both ends of string
// Parameters: psz String.
// Returns: Pointer to string
//----------------------------------------------------------------------------
PSZ FN_E strtrim(PSZ psz)
{
return strtrimleft(strtrimright(psz));
}
//----------------------------------------------------------------------------
// Description: Trim space from left of string
// Parameters: psz String.
// Returns: Pointer to string
//----------------------------------------------------------------------------
PSZ FN_E strtrimleft(PSZ psz)
{
PSZ pszWS = psz;
Assert(psz);
while (isascii(*pszWS) && isspace(*pszWS))
pszWS++;
if (pszWS != psz)
strcpy(psz, pszWS);
return psz;
}
//----------------------------------------------------------------------------
// Description: Trim space from right of string
// Parameters: psz String.
// Returns: Pointer to string
//----------------------------------------------------------------------------
PSZ FN_E strtrimright(PSZ psz)
{
Assert(psz);
if (*psz)
{
PSZ pszWS = strchr(psz, '\0') - 1;
for (;;)
{
if (!isascii(*pszWS) || !isspace(*pszWS))
{
pszWS[1] = '\0';
return psz;
}
if (pszWS == psz)
break;
pszWS--;
}
psz[0] = '\0';
}
return psz;
}
//----------------------------------------------------------------------------
// Description: Run standard test suite
// Parameters: sTest Test to run.
// 0 Run all default tests (except).
// Returns: TRUE if successful.
//----------------------------------------------------------------------------
#if COMPILE_TEST
BOOL FN StringTest(SHORT sTest)
{
static PSZ apsz[] =
{
"-2147483647",
"2147483647",
"-2147483648",
"2147483648",
"-32767",
"32767",
"-32768",
"32768",
"65536",
"065536",
" 65536 ",
"65537",
"0xFFFF",
"0xFFFF",
"0x10000",
"0xFFFFFFFF",
"4294967295",
NULL
};
static PSZ apszArray[20];
static CHAR szStr[100] = "d\0f\0g\0c\0b\0e\0i\0h\0a\0";
CHAR szBuf[10];
PSZ psz;
SIZET i;
SHORT s;
USHORT us;
LONG l;
ULONG ul;
NOTUSED(sTest);
Output("Count = %d (5)\n", strcnt("dabcddefk9d", 'd'));
Output("Hash = %08lX\n", strhash("ABCDEF"));
Output("String = [%s]\n", strnzcpy(szBuf, "ABCDEFGHIJK", 5));
Output("String = [%s]\n", strskipws(" This is a test "));
Output("String = [%s]\n", strtrimleft(" This is a test "));
Output("String = [%s]\n", strtrimright(" This is a test "));
Output("String = [%s]\n", strskipws(" This is a test "));
for (i = 0; strextract(szBuf, ";test+is-a/test", i, ";+-/"); ++i)
Output("Extract %2d: [%s]\n", i, szBuf);
for (i = 0; apsz[i]; ++i)
{
Output("String = %s\n", apsz[i]);
if (strvalidshort(apsz[i], &s))
Output("SHORT = %hd\n", s);
else
Output("SHORT = invalid!\n");
if (strvalidushort(apsz[i], &us))
Output("USHORT = %hu\n", us);
else
Output("USHORT = invalid!\n");
if (strvalidlong(apsz[i], &l))
Output("LONG = %ld\n", l);
else
Output("LONG = invalid!\n");
if (strvalidulong(apsz[i], &ul))
Output("ULONG = %lu\n", ul);
else
Output("ULONG = invalid!\n");
}
str2array(szStr, apszArray, 0);
for (i = 0; apszArray[i]; ++i)
Output(" %s\n", apszArray[i]);
Output("\n");
strarraysort(apszArray, 0);
for (i = 0; apszArray[i]; ++i)
Output(" %s\n", apszArray[i]);
if ((psz = (PSZ)strarrayfind("a", apszArray, 0)) == NULL
|| strcmp(psz, "a") != 0
|| strarrayfind("z", apszArray, 0) != NULL)
return FALSE;
if(!strisphone("09ayAY"))
return FALSE;
if(strisphone("09ayAYqQzZ"))
return FALSE;
if(!strisnumeric("0123456789"))
return FALSE;
if(strisnumeric("0123456789a"))
return FALSE;
// if(strisnumeric2("0123456789ABCZ"))
// return FALSE;
if (!strisvalid("a(abqa", "??[a-z~q]+?[A-Z]*\\a"))
return FALSE;
return TRUE;
}
#endif
//----------------------------------------------------------------------------
//------------------------------- End of File --------------------------------
//----------------------------------------------------------------------------